package gare.quai;

import gare.Gare;
import thread.Train;
import thread.Voyageur;

/**
 * Objet partagé
 */
public class EspaceQuai {

	public static int NB_VOIES = 5;

	private Gare gare;

	private Voie lesVoies[] = new Voie[NB_VOIES];

	private int nbOcuppee = 0;

	public EspaceQuai(Gare gare) {
		this.gare = gare;
		for (int i = 0; i < NB_VOIES; i++)
			lesVoies[i] = new Voie(i);
	}

	public synchronized void accueillirTrain(Train train) {
		System.out.println(train.toString() + " demande d'entrer le gare");
		while (nbOcuppee == NB_VOIES) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (Voie voie : lesVoies) {
			if (voie.estLibre()) {
				voie.accueillir(train);
				nbOcuppee++;
				System.out.println(train.toString() + " arrive au "
						+ voie.toString());
				break;
			}
		}
		gare.getEspaceVente().ajouterNombrePlace(train.getNbPlaceDisponible());

		afficher();
	}

	/**
	 * Sortir le train, laisser vide le voie puis notifier les autres trains qui
	 * attend d'entrer.
	 */
	public synchronized void sortirTrain(Train train) {
		while (train.getNombreReservation() > train.getNombreVoyageur()) {
			System.out.println("Départ de " + train.toString()
					+ "est reporté pour attente des voyageurs.");
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (Voie voie : lesVoies) {
			if (voie.occupePar(train)) {
				voie.accueillir(null);
				nbOcuppee--;
				gare.getEspaceVente().enleverNombrePlace(
						train.getNbPlaceDisponible()
								- train.getNombreReservation());
				System.out.println(train.toString() + " départ du "
						+ voie.toString());
				notify();
				break;
			}
		}
		afficher();
	}

	/**
	 * Cherche une place disponible à partir des trains stationnés dans le gare.
	 * 
	 * @return Le train pour la place trouvée.
	 */
	synchronized public Train getPlace() {
		System.out.println("Cherche place");
		for (Voie voie : lesVoies) {
			if (!voie.estLibre() && voie.getTrain().getNbPlaceDisponible() > 0
					&& (voie.getTrain().getetatArreter() == false)) {
				voie.getTrain().reserverPlace();
				return voie.getTrain();
			}
		}
		return null;
	}

	public void afficher() {
		System.out.println(">>>");
		for (Voie voie : lesVoies) {
			voie.afficher();
		}
		System.out.println("\n<<<");
	}

	/**
	 * Monte le voyageur puis notifie les trains qui attend ses voyageurs pour
	 * vérifier à nouveau.
	 */
	public synchronized void monter(Voyageur voyageur) {
		System.out.println(voyageur.toString() + " est en cour de monter "
				+ voyageur.getBillet().getTrain().toString());
		voyageur.getBillet().getTrain().monter(voyageur);
		// Notifie le train qui attend son voyageur.
		notify();
	}
}
